package com.wenbo.transfor;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.IoUtil;
import com.sun.java.swing.plaf.windows.WindowsLabelUI;
import com.wenbo.utils.Threads;
import lombok.extern.slf4j.Slf4j;


import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.*;
import java.net.BindException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.ThreadPoolExecutor;

public class ReceiveFileThread extends Thread{

	//private Logger logger = LoggerFactory.getLogger(ReceiveFileThread.class);

	private Socket socket;
	private JFrame frame;
	//private DataInputStream dis;
	//private DataOutputStream dos;
	private RandomAccessFile rad;
	private JLabel label;
	private Container contentPane;
	private JTextArea textArea;

	private JButton open;

	private final Object lock;

	private int counter;
	private JTextField time;

	private Timer timer;

	private boolean resume = true;

	private ThreadPoolExecutor threadPoolExecutor;

	private int count = 0;

	private String disk;


	public ReceiveFileThread(Object lock, ThreadPoolExecutor threadPoolExecutor){
		this.lock = lock;
		this.threadPoolExecutor = threadPoolExecutor;
	}

	@Override
	public void run(){
		frame=new JFrame("接收文件");
		//传输界面
		frame.setSize(479, 412);
		//frame.setLocation(2000, 533);
		frame.setLayout(null);
		contentPane = frame.getContentPane();
		JLabel titleLabel = new JLabel("文件接收端",null,SwingConstants.LEFT);
		titleLabel.setFont(new Font("华文隶书",Font.BOLD,22));
		titleLabel.setBounds(140,0,200,30);
		contentPane.add(titleLabel);
		label = new JLabel("准备就绪...",null,SwingConstants.LEFT);
		label.setBounds(50,30,400,30);
		label.setUI(new WindowsLabelUI());
		contentPane.add(label);
		time = new JTextField("0");
		time.setForeground(Color.RED);
		time.setEditable(false);
		time.setBounds(300,0,50,30);
		int minute = counter / 60;
		int second = counter % 60;
		time.setText("耗时:"+minute+"分"+second+"秒");
		time.setBounds(350,0,100,30);
		contentPane.add(time);

		JLabel openDir = new JLabel("打开存放目录:");
		openDir.setBounds(20,125,100,30);
		contentPane.add(openDir);
		open = new JButton("打开");
		open.setBounds(115,125,70,25);
		open.setEnabled(false);
		contentPane.add(open);
		open.addActionListener((ActionEvent e)->{
			try {
				Desktop.getDesktop().open(new File(disk));
			} catch (IOException ex) {
				ex.printStackTrace();
			}
		});
		textArea = new JTextArea(200, 420);
		textArea.setForeground(Color.BLUE);
		textArea.setBackground(Color.lightGray);
		textArea.setPreferredSize(new Dimension(420,200));
		JScrollPane scrollableTextArea = new JScrollPane(textArea);
		scrollableTextArea.setBounds(20,160,420,200);
		scrollableTextArea.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
		scrollableTextArea.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
		contentPane.add(scrollableTextArea);

		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frame.setVisible(true);
		frame.setResizable(false);
		ServerSocket connectSocket = null;
		try {
			connectSocket = new ServerSocket(10052);
			while (true){
				socket = connectSocket.accept();
				threadPoolExecutor.execute(new ReceiveTask());
			}
		} catch (IOException e) {
			e.printStackTrace();
			if (e instanceof BindException) {
				JOptionPane.showMessageDialog(frame, "端口:10052被占用!", "提示", JOptionPane.WARNING_MESSAGE);
				frame.dispose();
				IoUtil.close(socket);
				Threads.shutdownAndAwaitTermination(threadPoolExecutor);
				//logger.error(":",e);
				System.exit(0);
			}
		}
	}
	class ReceiveTask implements Runnable{
		@Override
		public void run() {
			try {
					DataInputStream dis = new DataInputStream(new BufferedInputStream(socket.getInputStream()));
					DataOutputStream dos = new DataOutputStream(new BufferedOutputStream(socket.getOutputStream()));
					String ok = dis.readUTF();
					int permit = -1;
					if ("ok".equals(ok) && 0 == count) {
						permit = JOptionPane.showConfirmDialog(frame, "是否接收文件", "文件传输请求：", JOptionPane.YES_NO_OPTION);
					}else {
						permit = JOptionPane.YES_OPTION;
					}
					if (permit == JOptionPane.YES_OPTION) {
						count ++ ;
						String filename = dis.readUTF();

						String suffix = filename.substring(filename.lastIndexOf("."));
						String showName = filename.substring(0, filename.lastIndexOf("."));
						String property = System.getProperty("user.dir");
						disk = property.substring(0, property.indexOf("\\") + 1);
//					JFileChooser fc = new JFileChooser(disk);
//					fc.setDialogTitle("选择保存文件的路径");
//					int status = fc.showSaveDialog(null);
//					String realPath = "";
//					if (status == JFileChooser.APPROVE_OPTION) {
//						realPath = fc.getSelectedFile().toString();
//
//					}
						dos.writeUTF("ok");
						dos.flush();
						String location = disk + filename;
						File file = new File(location + ".temp");
						rad = new RandomAccessFile(location + ".temp", "rw");
						//获得文件大小
						long size = 0;
						if (file.exists() && file.isFile()) {
							size = file.length();
						}
						dos.writeLong(size);//发送已接收的大小
						dos.flush();
						long allSize = dis.readLong();
						String rsp = dis.readUTF();

						int barSize = (int) (allSize / 1024);
						int barOffset = (int) (size / 1024);
						if (showName.length() > 20) {
							showName = showName.substring(0, 20) + ".." + suffix;
						} else {
							showName = showName + suffix;
						}
						label.setText(showName + " 接收中");

						JProgressBar progressbar = new JProgressBar();//进度条
						contentPane.add(progressbar);
						progressbar.setBounds(50, 65, 230, 25);
						JButton cancel = new JButton("取消");
						cancel.addActionListener((ActionEvent e) -> {
							JButton source = (JButton) e.getSource();
							String message = "已取消接收，连接关闭！";
							String text = source.getText();
							if ("完成".equals(text)) {
								message = "完成接收,连接即将关闭";
							}
							JOptionPane.showMessageDialog(frame, message, "提示：", JOptionPane.INFORMATION_MESSAGE);
							label.setText(" " + text + "接收");
							IoUtil.close(socket);
							IoUtil.close(dis);
							IoUtil.close(dos);
							IoUtil.close(rad);
							frame.dispose();
							Threads.shutdownAndAwaitTermination(threadPoolExecutor);
							System.exit(0);
						});
						contentPane.add(cancel);
						cancel.setBounds(290, 65, 65, 25);
						progressbar.setOrientation(JProgressBar.HORIZONTAL);
						progressbar.setMinimum(0);
						progressbar.setMaximum(barSize == 0?1:barSize);
						progressbar.setValue(barOffset);
						progressbar.setStringPainted(true);
						progressbar.setPreferredSize(new Dimension(150, 20));
						progressbar.setBorderPainted(true);
						progressbar.setBackground(Color.pink);

						//接收文件
						if (rsp.equals("ok")) {
							rad.seek(size);
							long length = 0;
							long allLength = 0;
							setTime();
							byte[] buf = new byte[1024];
							while ((length = dis.read(buf, 0, buf.length)) != -1) {
								allLength+=length;
								rad.write(buf, 0, (int)length);
								progressbar.setValue(++barOffset);
							}
							System.out.println("receive:"+Thread.currentThread().getName());
							System.out.println("allLength:" + allLength);
						}
						if (rad.length() < allSize) {
							label.setText(showName + " 对方已取消");
							return;
						}
						cancel.setText("完成");
						label.setText("文件保存在: " + disk + showName);
						label.setForeground(Color.RED);
						label.setFont(new Font("微软雅黑", Font.BOLD, 12));
						rad.close();
						//文件重命名
						File rename = FileUtil.rename(file, filename, true);
						timer.cancel();
						textArea.append(disk+filename);
						textArea.append("\n");
						int lineCount = textArea.getLineCount();
						if (lineCount >0){
							open.setEnabled(true);
						}
					}
			} catch(IOException e){
				e.printStackTrace();
				Threads.shutdownAndAwaitTermination(threadPoolExecutor);
				label.setText(" 已取消发送，连接关闭！");
			}
		}

	}
	private void setTime(){
		TimerTask task = new TimerTask(){
			@Override
			public void run() {
				synchronized (lock) {
					counter++;
					int minute = counter / 60;
					int second = counter % 60;
					time.setText("耗时:" + minute + "分" + second + "秒");
				}
			}};
		//计时器
		timer = new Timer();
		timer.schedule(task,0,1000);
	}
	class cancelActionListener implements ActionListener{
		@Override
		public void actionPerformed(ActionEvent e){
			try {
				rad.close();
				JOptionPane.showMessageDialog(frame, "已取消接收，连接关闭！", "提示：", JOptionPane.INFORMATION_MESSAGE);
				label.setText(" 取消接收,连接关闭");
				frame.dispose();
			} catch (IOException e1) {
				//logger.error(":",e1);
				e1.printStackTrace();
			}
		}
	}
	static class TextAreaExample {
		TextAreaExample() {
			// Create and set up the window.
			final JFrame frame = new JFrame("JScrollPane案例-一点教程网");

			// Display the window.
			frame.setSize(500, 500);
			frame.setVisible(true);
			frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

			// set flow layout for the frame
			frame.getContentPane().setLayout(new FlowLayout());

			JTextArea textArea = new JTextArea(20, 20);
			JScrollPane scrollableTextArea = new JScrollPane(textArea);

			scrollableTextArea.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
			scrollableTextArea.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);

			frame.getContentPane().add(scrollableTextArea);
			new Thread(()->{
				for (int i = 0; i < 100; i++) {
					textArea.append("你好呀...");
					textArea.append("\n");
				}
			}).start();
		}
	}
		public static void main(String[] args) {
			new TextAreaExample();

	}

}